﻿/***********************************************************************
 *            Project: CoreCms
 *        ProjectName: 核心内容管理系统                                
 *                Web: https://www.corecms.net                      
 *             Author: 大灰灰                                          
 *              Email: jianweie@163.com                                
 *         CreateTime: 2021/1/31 21:45:10
 *        Description: 暂无
 ***********************************************************************/

using CoreCms.Net.Configuration;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using NLog;
using System;
using System.Threading.Tasks;
using CoreCms.Net.Caching.AutoMate.RedisCache;
using Essensoft.Paylink.WeChatPay;
using Essensoft.Paylink.WeChatPay.V2;
using Essensoft.Paylink.WeChatPay.V2.Notify;

namespace CoreCms.Net.Web.WebApi.Controllers.PayNotify
{
    /// <summary>
    ///     微信支付异步通知
    /// </summary>
    [Route("Notify/[controller]/[action]")]
    public class WeChatPayController : ControllerBase
    {
        private readonly ICoreCmsBillPaymentsServices _billPaymentsServices;
        private readonly ICoreCmsBillRefundServices _billRefundServices;
        private readonly IWeChatPayNotifyClient _client;
        private readonly IRedisOperationRepository _redisOperationRepository;

        private readonly IWeChatPayConfigServices _weChatPayConfigServices;


        /// <summary>
        ///     构造函数
        /// </summary>
        public WeChatPayController(
            IWeChatPayNotifyClient client
            , ICoreCmsBillPaymentsServices billPaymentsServices, ICoreCmsBillRefundServices billRefundServices, IRedisOperationRepository redisOperationRepository, IWeChatPayConfigServices weChatPayConfigServices)
        {
            _client = client;
            _billPaymentsServices = billPaymentsServices;
            _billRefundServices = billRefundServices;
            _redisOperationRepository = redisOperationRepository;
            _weChatPayConfigServices = weChatPayConfigServices;
        }

        /// <summary>
        ///     统一下单支付结果通知
        /// </summary>
        [HttpPost]
        [Route("m-{appid}")]
        public async Task<IActionResult> Unifiedorder([FromRoute(Name = "appid")] string appid)
        {
            try
            {
                //NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "微信支付成功接收appid", JsonConvert.SerializeObject(appid));

                var config = await _weChatPayConfigServices.QueryByClauseAsync(p => p.isDefault == true && p.isEnable == true && p.appId == appid);
                //构建linkPay请求配置实体
                var payOptions = new WeChatPayOptions
                {
                    AppId = config.appId,
                    MchId = config.mchId,
                    APIKey = config.apiKey,
                    APIv3Key = config.apiV3Key,
                    Certificate = config.certificate,
                    RsaPublicKey = config.rsaPublicKey,
                    SubAppId = config.subAppId,
                    SubMchId = config.subMchId
                };


                var notify = await _client.ExecuteAsync<WeChatPayUnifiedOrderNotify>(Request, payOptions);
                if (notify.ReturnCode == WeChatPayCode.Success)
                {
                    await _redisOperationRepository.ListLeftPushAsync(RedisMessageQueueKey.WeChatPayNotice, JsonConvert.SerializeObject(notify));
                    NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "微信支付成功回调", JsonConvert.SerializeObject(notify));
                    return WeChatPayNotifyResult.Success;
                }
                else
                {
                    NLogUtil.WriteAll(LogLevel.Error, LogType.Order, "微信支付成功回调", JsonConvert.SerializeObject(notify));
                }
                return NoContent();
            }
            catch (Exception ex)
            {
                NLogUtil.WriteAll(LogLevel.Error, LogType.Order, "微信支付成功回调异常", "统一下单支付结果通知", ex);
                return NoContent();
            }
        }

        /// <summary>
        ///     退款结果通知
        /// </summary>
        [HttpPost]
        public async Task<IActionResult> Refund()
        {
            try
            {
                var config = await _weChatPayConfigServices.QueryByClauseAsync(p => p.isDefault == true && p.isEnable == true);
                //构建linkPay请求配置实体
                var payOptions = new WeChatPayOptions
                {
                    AppId = config.appId,
                    MchId = config.mchId,
                    APIKey = config.apiKey,
                    APIv3Key = config.apiV3Key,
                    Certificate = config.certificate,
                    RsaPublicKey = config.rsaPublicKey,
                    SubAppId = config.subAppId,
                    SubMchId = config.subMchId
                };

                var notify = await _client.ExecuteAsync<WeChatPayRefundNotify>(Request, payOptions);
                NLogUtil.WriteAll(LogLevel.Trace, LogType.Refund, "微信退款结果通知", JsonConvert.SerializeObject(notify));

                if (notify.ReturnCode != WeChatPayCode.Success) return NoContent();
                {
                    var memo = JsonConvert.SerializeObject(notify);

                    var status = notify.RefundStatus == WeChatPayCode.Success
                        ? (int)GlobalEnumVars.BillRefundStatus.STATUS_REFUND
                        : (int)GlobalEnumVars.BillRefundStatus.STATUS_FAIL;

                    await _billRefundServices.UpdateAsync(p => new CoreCmsBillRefund { memo = memo, updateTime = DateTime.Now, status = status }, p => p.refundId == notify.OutTradeNo);

                    //这个返回只是告诉回调这个业务我们接收到了。
                    return WeChatPayNotifyResult.Success;
                }

            }
            catch (Exception ex)
            {
                NLogUtil.WriteAll(LogLevel.Trace, LogType.Refund, "微信退款结果通知", "退款结果通知", ex);

                return NoContent();
            }
        }
    }
}